#include "Camera.hpp"

#include <iostream>

//////////////////////
Vector Camera::PixelTo3d( int i, int j)
{
    i -= height_px/2;
    j -= width_px/2;

    
    Vector result = position + normal*( (real_t)i / height_px) * height   +   direction * normal * ( (real_t)j / width_px) * width;
    return result;
}

Vector Camera::GetRandomDirection()
{
    //boost::mutex::scoped_lock lock( _monitor_random);
    
    //boost::random::uniform_real_distribution<real_t> range( - sin_angle, + sin_angle);
    
    //real_t sin_angle = std::sin( angle/180.0*PI);



     //   std::cout << "Gen random" << std::endl;
        
      //  real_t random_1 = range( _rng);
      //  real_t random_2 = range( _rng);
    
    //std::cout << random_1 << std::endl;
        
    Vector result = direction ;// + normal * random_1 + direction * normal * random_2;
    result.normalize();
    return result;
}
Vector Camera::GetDirection( int i, int j)
{
    i -= height_px/2;
    j -= width_px/2;
    
    
    Vector result = direction + normal*( (real_t)i / height_px) * sin_angle  +  direction * normal * ( (real_t)j / width_px) * sin_angle;
    result.normalize();
    return result;   
}
//////////////////////
void Camera::SaveImage()
{
    SaveImage("img");
}
void Camera::SaveImage ( std::string file_name )
{
    ilSetData( _bitmap);
    
    ILenum Type = config.output_format;

    ilSave( Type, file_name.c_str());

    std::cout << std::endl << ilGetError();
}
void Camera::SetPixel ( int i, int j, Color &color )
{
    if ( i >= height_px || j >= width_px)
        return;

    {
        //boost::mutex::scoped_lock  lock ( _monitor_set );
    
        _bitmap[ i * width_px * 3 + j*3 + 0] = color.r;
        _bitmap[ i * width_px * 3 + j*3 + 1] = color.g;
        _bitmap[ i * width_px * 3 + j*3 + 2] = color.b;
    }
    //std::cout << color.r;
    //std::cout << color.g;
    //std::cout << color.b;
}
void Camera::SetAverPixel ( int i, int j, Color &color )
{
    if ( i >= height_px || j >= width_px)
        return;
    
    _bitmap[ i * width_px * 3 + j*3 + 0] = ( color.r + _bitmap[ i * width_px * 3 + j*3 + 0])/2;
    _bitmap[ i * width_px * 3 + j*3 + 1] = ( color.g + _bitmap[ i * width_px * 3 + j*3 + 1])/2;
    _bitmap[ i * width_px * 3 + j*3 + 2] = ( color.b + _bitmap[ i * width_px * 3 + j*3 + 2])/2;
}
//////////////////////
Camera::Camera()
{
    position  = config.camera_position;
    
    direction = config.camera_direction;
    direction.normalize();

    normal    = config.camera_normal;
    normal.normalize();
    
    width_px  = config.width_px;
    height_px = config.height_px;
    
    width     = config.width;
    height    = config.height;
    
    angle     = config.angle;
    sin_angle = std::sin( angle*PI/180.0);
    ///
    ilInit();
    ilGenImages( 1, &_image_id);

    ILuint  Width = config.width_px;
    ILuint  Heigh = config.height_px;
    ILuint  Depth = 0;
    ILubyte Bpp   = 3;
    ILenum  Format = IL_RGB;

    ILenum  Type = IL_FLOAT;
    int     *Data = NULL;
    
    ilBindImage( _image_id);
    ilTexImage( Width, Heigh, Depth, Bpp, Format, Type, Data);

    _bitmap = new float[ Width*Heigh*3];
}
Camera::~Camera()
{
    ilDeleteImages( 1, &_image_id);
    delete [] _bitmap;
}


